/**
 * @file cout_rd_buf.cpp
 * @author your name (you@domain.com)
 * @brief 演示如何在程序运行过程中，方便地重定向输出
 * @version 0.1
 * @date 2022-04-12
 * 
 * @copyright Copyright (c) 2022
 * 
 */

#include <iostream>
#include <fstream>
#include <string>

class redirect_cout_region
{
    using buftype = decltype(std::cout.rdbuf());

    std::ofstream ofs;
    buftype buf_backup;

public:
    /**
     * @brief 把cout重定向到文件中
     * 
     * @param filename 重定向目标文件名
     */
    explicit redirect_cout_region(const std::string& filename)
    : ofs{filename}
    , buf_backup{std::cout.rdbuf(ofs.rdbuf())}
    {}

    /**
     * @brief 默认构造函数，禁用cout输出
     * 
     */
    redirect_cout_region(void)
    : ofs{}
    , buf_backup{std::cout.rdbuf(ofs.rdbuf())}
    {}

    /**
     * @brief 析构函数，还原cout输出重定向
     * 
     */
    ~redirect_cout_region(void)
    {
        std::cout.rdbuf(buf_backup);
    }
};

int main(void)
{
    std::cout<< "this line will be printed in console: " << __LINE__ << std::endl;

    {
        redirect_cout_region la("a.txt");
        std::cout<< "this line will be printed in a.txt: " << __LINE__ << std::endl;
    }

    std::cout<< "this line will be printed in console: " << __LINE__ << std::endl;

    {
        redirect_cout_region lb("b.txt");
        std::cout<< "this line will be printed in b.txt: " << __LINE__ << std::endl;
    }

    std::cout<< "this line will be printed in console: " << __LINE__ << std::endl;

    {
        redirect_cout_region ln;
        std::cout<< "this line will not be printed: " << __LINE__ << std::endl;
    }

    std::cout<< "this line will be printed in console: " << __LINE__ << std::endl;
}